package com.des1gn.retry;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @ClassName RetryAspect
 * @Description 自动重试触发AOP
 * @Author Des1gn
 * @Version 1.0
 **/
@Aspect
@Component
@Slf4j
@RequiredArgsConstructor
public class RetryAspect {

    private final HttpServletRequest request;

    @Pointcut("@annotation(com.des1gn.retry.RetryEnable)")
    public void retryApi() {
    }

    @Around("retryApi()")
    public Object aspectAround(ProceedingJoinPoint joinPoint) {
        try {
            return joinPoint.proceed();
        } catch (Throwable e) {
            //重试调用
            retryPush(joinPoint);
            throw new RuntimeException(e);
        }
    }

    private void retryPush(ProceedingJoinPoint joinPoint){
        try {
            request.getSession();
            Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
            RetryEnable retryEnable = method.getAnnotation(RetryEnable.class);
            RetryCounter retryCounter = RetryCounter.builder()
                    .maxCount(retryEnable.retryCount())
                    .targetClass(joinPoint.getTarget().getClass())
                    .targetMethod(method.getName())
                    .paramterClassArges(method.getParameterTypes())
                    .targetArgs(joinPoint.getArgs())
                    .build();
            RetryProcessorManage.push(retryCounter);
        }catch (Exception e){

        }
    }

}
